#题目概述：给定任意正整数，返回小于等于它自身，完全由2，3组成的数字的个数， 例如给出99， 满足条件的数为33,32,23,22,3,2共6个，返回值为6.
#两种解题思路，第一种，暴力历遍法， 把所有的数每一个都做判断， 是否只包含2合3
#优点是逻辑简单， 缺点是占用资源， 耗费时间， 尤其到10的18次方的时候，恐怕计算机算力不够，时间上也耗不起
#所以20分的可以拿这个思路做

#定义一个函数判断是否只包含2，3， 换个说法， 不包含0，1，4，5，6，7，8，9


#############解法一##########################
def judgenumber(i):
    stri=str(i)
    if '0' in stri:
        return False
    if '1' in stri:
        return False
    if '4' in stri:
        return False
    if '5' in stri:
        return False
    if '6' in stri:
        return False
    if '7' in stri:
        return False
    if '8' in stri:
        return False
    if '9' in stri:
        return False
    #其它，也就是只包含2，3返回真
    return True

y=0
N=int(input("请输入一个小于100000的正整数:"))
#注意python的列表不包含最后一个数， 所以需要N+1
for x in range(N+1):
    if judgenumber(x):
        print(x)
        y=y+1
print("第1种方法只包含2，3的数字有{}个".format(y))

#############################################

#第二种思路， 一个数只包含2和3， 是不是很熟悉，只包含两个数的，是什么？

#是不是2进制数？ 怎么理解呢？把2，和3，替换成0，1是不是就好理解了
#一个数只包含0和1，看起来是不是就是一串2进制数字？ 例如11110000，1010101，10001111
#那么本题的思路就是做一个由数字2，3组成的2进制数，把“2”，“3”理解为字符串， 由两个字符串构成的2进制数
#题目给定一个数N， 我们第一步返回出在数字N内最大的包含2，3的数，得到这个数后， 我们转为2进制数后做排列组合算出复核的个数



#第一步，给出一个任意正整数， 返回它所包含的最大的由3和2组成的数
def test(i):
    x=list(str(i))

    for y in range(1,len(x)+1):
        #返回每一位的由3，2组成的对应的数， 如，8改为3，9改为3，2，3本身不变， 0和1小于2，所以需要往前借一位，借完后大于3，改为3，前一位做减法减一
        #print('倒数第{}位,值是{}'.format(y,x[-y]))
        if int(x[-y])<2:
            x[-y]='3'
            if y+1<=len(x):
                x[-y-1]=int(x[-y-1])-1
            else:
                pass
                x='3'*(len(x)-1)
                return test(x)
        if int(x[-y])>3:
            x[-y]='3'
    print("{}内包含的最大的由2，3组成的数是{}".format(i,''.join(x) ))
    return int(''.join(x))        

#第二步，给定由2，3做成的数， 返回小于等于它自身，且也是由2，3组成的所有数的个数的总和。
#给定一个只包含3和2的数， 返回它所包含的所有由3，2组成的个数， 例如给出323，转化为101，它包含的小于等于他的数的个数为"1"+"101"  也就是1101 化为是十进制数为13 减去十进制1,结果是十进制的12个
#323,322,233,232,223,222,33,32,23,22,3,2  正好12个
def test1(i):
    #把i由数字转为字母，判断i的长度， 是几位数
    x=str(i)
    result0=x.replace('3','1').replace('2','0')
    #给定一个二进制数，返回小于等于这个二进制数的所有可能性的方法
    result=int('1'+result0,2)-1
    return(result)
        
print("第二种方法的结果为:",test1(test(N)))
    


